# -*- coding : "utf-8" -*-
# @姓名       : GUI
# @日期       : 2023/2/12 20:00
# @FileName  ： models.py
# @Software  ： PyCharm
import logging
from dataclasses import asdict, dataclass
import allure
import yaml
from commons import settings
from commons.templates import Template


logger = logging.getLogger(__name__)


@dataclass
class CaseInfo:
    """用例格式校验"""
    title: str
    request: dict
    extract: dict
    validate: dict
    parametrize: list = ""
    epic: str = settings.allure_epic
    feature: str = settings.allure_feature
    story: str = settings.allure_story

    def to_yaml(self) -> str:
        """序列化成yaml字符串"""
        yaml_str = yaml.dump(asdict(self), allow_unicode=True)
        return yaml_str

    @classmethod
    def by_yaml(cls, yaml_str):
        """反序列化"""
        obj = cls(**yaml.safe_load(yaml_str))
        return obj

    @allure.step("断言")
    def assert_all(self):
        if not self.validate:
            return
        print("xxxxxxx"*5)
        print(self.validate.items())

        for assert_type, assert_data in self.validate.items():
            for msg, data in assert_data.items():
                a, b = data[0], data[1]
                # print(assert_type, a, b, msg)
                # 断言封装
                match assert_type:
                    case "equals":
                        logger.info(f"assert {a} == {b}, {msg}")
                        assert a == b, msg
                    case "not_equals":
                        logger.info(f"assert {a} != {b}, {msg}")
                        assert a != b, msg
                    case "contains":
                        logger.info(f"assert {a} in {b}, {msg}")
                        assert a in b, msg
                    case "not_contains":
                        logger.info(f"assert {a} not in {b}, {msg}")
                        assert a not in b, msg

    def ddt(self) -> list:  # 返回一个列表，列表中应该包含N个 注入了变量的 CaseInfo
        case_list = []
        if not self.parametrize:  # 没有使用数据驱动测试
            case_list.append(self)
        else:  # 使用了数据驱动测试
            args_name = self.parametrize[0]
            args_value_list = self.parametrize[1:]
            self.parametrize = []
            for args_value in args_value_list:
                d = dict(zip(args_name, args_value))  # key+ n 个vlaue = n个字典
                # d 就是数据驱动测试的变量，应输入到用例中
                case_info_str = self.to_yaml()  # 转字符串
                case_info_str = Template(case_info_str).render(d)  # 输入变量
                case_info = self.by_yaml(case_info_str)  # 转成类
                case_list.append(case_info)  # 加入到返回值
        return case_list
